﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using UIControls;
using System.Reflection;
using BO;
using UI.Core;
using System.Runtime.InteropServices;
using UIControls.Grid;
using BrightIdeasSoftware;

namespace UI.Security
{
    public partial class RoleAcessForm : FormBase, IMenuForm
    {
        readonly Color VisibleColor = Color.Red;
        readonly Color ReadOnlyColor = Color.Blue;

        public RoleAcessForm()
        {
            
            InitializeComponent();

            cmbRole.ComboBox.DropDownStyle = ComboBoxStyle.DropDownList;
            rbNormal.Checked = true;
            rbVisible.ForeColor = VisibleColor;
            rbReadOnly.ForeColor = ReadOnlyColor;

            controlTree.DrawMode=formTree.DrawMode = TreeViewDrawMode.OwnerDrawText;
            controlTree.HideSelection = formTree.HideSelection = false;
           formTree.DrawNode += new DrawTreeNodeEventHandler(treeControl_DrawNode);
           controlTree.DrawNode += new DrawTreeNodeEventHandler(treeControl_DrawNode);
        }
        Assembly asm = Assembly.Load(GlobalVar.UIAssembly);
        private SysRoleList roleList;
        private void RoleAcessForm_Load(object sender, EventArgs e)
        {       
            foreach (var t in asm.GetTypes())
            {
                TreeNode node = null;
                if (t.Namespace == "UI.Security")
                {
                    continue;
                }
                if (t.GetInterface("IMenuForm")==null)
                {
                    continue;
                }
           
                dynamic formObj = asm.CreateInstance(t.FullName);
                var p = formObj.Text;
                if (p != null)
                {
                    node=new TreeNode(p);
                    node.Tag = t.FullName;
                }
                if (node != null)
                {
                    node.Tag = t.FullName;
                    formTree.Nodes.Add(node);
                }
            }
            cmbRole.ComboBox.SelectedValueChanged += new EventHandler(cmbRole_SelectedValueChanged);
            roleList = ListFactory<SysRoleList>.GetList("IsInactive=0");
            cmbRole.ComboBox.DataSource = roleList;
            cmbRole.ComboBox.DisplayMember = "RoleName";
            cmbRole.ComboBox.ValueMember = "RoleName";
         
            formTree.NodeMouseDoubleClick += new TreeNodeMouseClickEventHandler(treeControl_NodeMouseDoubleClick);
            formTree.NodeMouseClick += treeControl_NodeMouseClick;
            controlTree.NodeMouseClick += treeControl_NodeMouseClick;
        }

        void treeControl_NodeMouseClick(object sender, TreeNodeMouseClickEventArgs e)
        {
            if (e.Button != System.Windows.Forms.MouseButtons.Right)
                return;
            var tag = e.Node.Tag;
            if (tag == null)
                return;

            if (rbNormal.Checked)
                e.Node.BackColor = Color.Empty;

            if (rbReadOnly.Checked)
                e.Node.BackColor = Color.Blue;
            if (rbVisible.Checked)
                e.Node.BackColor = Color.Red;
            if (e.Node.TreeView == formTree)
            {
                setFormAccess(tag);
            }
            else if (e.Node.TreeView == controlTree)
            {
                setControlAccess(tag);
            }
        }

        private void setControlAccess(object tag)
        {
            var str = tag.ToString();
            var obj = list.FindControlAccess(CurFormType.FullName, str);
            if (obj == null)
            {
                if (rbNormal.Checked)
                    return;
                if (rbReadOnly.Checked)
                    obj = new RoleAccess() { FormName = CurFormType.FullName, ControlName = str, Enabled = true };

                if (rbVisible.Checked)
                    obj = new RoleAccess() { FormName = CurFormType.FullName, ControlName = str, Visible = true };
                obj.RoleName = cmbRole.ComboBox.SelectedValue.ToString();
                obj.OID = Guid.NewGuid().ToString();
                list.AddChild(obj);
            }
            else
            {
                if (rbNormal.Checked)
                    list.RemoveByOID(obj.OID);
                if (rbReadOnly.Checked)
                {
                    obj.Visible = false;
                    obj.Enabled = true;
                }

                if (rbVisible.Checked)
                {
                    obj.Enabled = false;
                    obj.Visible = true;
                }


            }
        }

        void setFormAccess(object tag)
        {

            var str = tag.ToString();
            var obj = list.FindFormAccess(str);
            if (obj == null)
            {
                if (rbNormal.Checked)
                    return;
                if (rbReadOnly.Checked)
                    obj = new RoleAccess() { FormName = str, ControlName = str, Enabled = true };

                if (rbVisible.Checked)
                    obj = new RoleAccess() { FormName = str, ControlName = str, Visible = true };
                obj.RoleName = cmbRole.ComboBox.SelectedValue.ToString();
                obj.OID = Guid.NewGuid().ToString();
                list.AddChild(obj);
            }
            else
            {
                if (rbNormal.Checked)
                    list.RemoveByOID(obj.OID);
                if (rbReadOnly.Checked)
                {
                    obj.Visible = false;
                    obj.Enabled = true;
                }

                if (rbVisible.Checked)
                {
                    obj.Enabled = false;
                    obj.Visible = true;
                }


            }
        }

        void treeControl_NodeMouseDoubleClick(object sender, TreeNodeMouseClickEventArgs e)
        {
            if (e.Button != System.Windows.Forms.MouseButtons.Left)
                return;
            var tName = e.Node.Tag.ToString();

            var form = asm.CreateInstance(tName) as UI.Core.FormBase;
            if (form == null)
                return;
            form.IsSecurityMode = true;
            gbForm.Controls.Clear();
            form.TopLevel = false;
            form.FormBorderStyle = System.Windows.Forms.FormBorderStyle.None;
            form.Dock = DockStyle.Fill;

            gbForm.Controls.Add(form);
            form.Visible = true;
            form.Visible = true;
            ClearEnvent(form);
            controlTree.Nodes.Clear();
    
           CurFormType = form.GetType();
           CurForm = form;
          
          LoadControlTree();

         

            controlTree.ExpandAll();
           
       
        }
        void LoadColumns(OSGrid grid)
        {
         
            if (grid.Columns.Count == 0)
                return;
            foreach(OLVColumn col in grid.Columns)
            {
                var str = grid.Name + "+" + col.Text;
                var cNode = controlTree.Nodes.Add(str);
                 var colName= grid.Name + "+" + col.Name;
                 cNode.Tag = colName;
                 var ac = list.FindControlAccess(CurFormType.FullName, colName);
                 if (ac == null)
                 {
                     cNode.BackColor = Color.Empty;
                 }
                 else
                 {
                     if (ac.Enabled)
                     {
                         cNode.BackColor = ReadOnlyColor;
                         col.HeaderForeColor = ReadOnlyColor;
                     }
                     if (ac.Visible)
                     {
                         cNode.BackColor = VisibleColor;
                         col.HeaderForeColor = VisibleColor;
                     }
                 }
            }
        }
        void LoadControlTree()
        {         
            FormBase form = CurForm;
            var flist = Utility.GetAllControl(CurFormType, CurForm);

            foreach (var f in flist)
            {
                var c = f.GetValue(form) as Control;
                if (c is OSGrid)
                    LoadColumns(c as OSGrid);
                if (c == null || c is IUIControl == false)
                    continue;

                var str = (c as IUIControl).LabelText;
                if (str.Length == 0)
                    return;


                var cNode = controlTree.Nodes.Add(str);
                cNode.ToolTipText = cNode.Text;
                cNode.Tag = c.Name;

                var ac = list.FindControlAccess(CurFormType.FullName, c.Name);
                if (ac == null)
                {
                    cNode.BackColor = Color.Empty;
                }
                else
                {
                    if (ac.Enabled)
                    {
                        cNode.BackColor = ReadOnlyColor;
                        c.ForeColor = ReadOnlyColor;
                    }
                    if (ac.Visible)
                    {
                        cNode.BackColor = VisibleColor;
                        c.ForeColor = VisibleColor;
                    }
                }


            }
        }

        FormBase CurForm;
        private void ClearEnvent(Control form)
        {
            return;
            var t = form.GetType();
            //取得事件表属性
            var e1 = t.GetProperty("Events",
                BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.ExactBinding);
            //获取值.
            var ev = e1.GetValue(form, null);
            //释放掉.
            var Obj = ev as IDisposable;
            Obj.Dispose();

            foreach (Control c in form.Controls)
            {

                ClearEnvent(c);
                if (c is IUIControl)
                    c.Click += new EventHandler(form_Click);
            }
        }

        void SetNodeBackColor(Control c)
        {
            if (rbNormal.Checked)
                c.BackColor = Color.Empty;

            if (rbReadOnly.Checked)
                c.BackColor = Color.Blue;
            if (rbVisible.Checked)
                c.BackColor = Color.Red;
        }

        void form_Click(object sender, EventArgs e)
        {
            var c = sender as Control;
            if (c == null)
                return;
            SetNodeBackColor(c);
        }


        protected void treeControl_DrawNode(object sender, DrawTreeNodeEventArgs e)
        {
            Color c = Color.LightGreen;
            if (e.Node.BackColor == Color.Empty)
                c = Color.LightGreen;
            else
                c = e.Node.BackColor;

            e.Graphics.FillRectangle(new SolidBrush(c), e.Bounds.Left - 15, e.Bounds.Top, 12, 12);
            e.Graphics.FillRectangle(new SolidBrush(Color.White), e.Bounds.Left - 12, e.Bounds.Top+3, 6, 6);
            e.Graphics.DrawString(e.Node.Text, this.Font, Brushes.Black,new Point( e.Bounds.Left,e.Bounds.Top));
            
            // e.DrawDefault = true;
        }


        void SetVisibleAndEnable(FormBase form)
        {
            if (list == null)
                return;
            var alist = list.Where(item => item.FormName == form.Name);
            foreach (var obj in alist)
            {
                var c = findControl(form, obj.ControlName);
                if (c != null)
                {
                    if (obj.Enabled)
                        c.BackColor = ReadOnlyColor;
                    if (obj.Visible)
                        c.BackColor = VisibleColor;
                }
            }
        }
        Control findControl(Control ctrl, string controlName)
        {
            foreach (Control c in ctrl.Controls)
            {
                if (c.Name == controlName)
                    return c;
            }
            foreach (Control c in ctrl.Controls)
            {//c.fin
                var r = findControl(c, controlName);
                if (r != null)
                {
                    return r;

                }
            }
            return null;

        }
        RoleAccessList list;
        private Type CurFormType;
        void cmbRole_SelectedValueChanged(object sender, EventArgs e)
        {
            gbForm.Controls.Clear();
            list = ListFactory<RoleAccessList>.GetList(string.Format("RoleName='{0}'", cmbRole.ComboBox.SelectedValue));

            foreach (TreeNode item in formTree.Nodes)
            {
                if (item.Tag == null)
                    continue;
                var str = item.Tag.ToString();
                var obj = list.FirstOrDefault(a => a.FormName == str && a.ControlName == str);
                if (obj == null)
                {
                    item.BackColor = Color.Empty;
                    continue;
                }
                if (obj.Enabled)
                    item.BackColor = ReadOnlyColor;
                if (obj.Visible)
                    item.BackColor = VisibleColor;
            }

            controlTree.Focus();
        }


        private void rbVisible_CheckedChanged(object sender, EventArgs e)
        {
            if(rbVisible.Checked)
                SetCursor(rbVisible.Text, VisibleColor);
        }

        private void rbReadOnly_CheckedChanged(object sender, EventArgs e)
        {
            if (rbReadOnly.Checked)
                SetCursor(rbReadOnly.Text, ReadOnlyColor);
        }

        private void rbNormal_CheckedChanged(object sender, EventArgs e)
        {
            if (rbNormal.Checked)
                SetCursor(rbNormal.Text, Color.Green);
        }

        void SetCursor(string curText, Color pColor)
        {
            Bitmap bitmap = new Bitmap(140, 25);
            Graphics g = Graphics.FromImage(bitmap);
            using (Font f = new Font(FontFamily.GenericSansSerif, 10))
                g.DrawString("←" + curText, f, new SolidBrush(pColor), 0, 0);

            formTree.Cursor =             
                controlTree.Cursor=
            CreateCursor(bitmap, 3, 3);
         
            bitmap.Dispose();
        }

        [DllImport("user32.dll")]
        public static extern IntPtr CreateIconIndirect(ref IconInfo icon);

        [DllImport("user32.dll")]
        [return: MarshalAs(UnmanagedType.Bool)]
        public static extern bool GetIconInfo(IntPtr hIcon, ref IconInfo pIconInfo);

        public Cursor CreateCursor(Bitmap bmp, int xHotSpot, int yHotSpot)
        {
          

            IconInfo tmp = new IconInfo();
            GetIconInfo(bmp.GetHicon(), ref tmp);
            tmp.xHotspot = xHotSpot;
            tmp.yHotspot = yHotSpot;
            tmp.fIcon = false;
            return new Cursor(CreateIconIndirect(ref tmp));
        }
        public struct IconInfo
        {
            public bool fIcon;
            public int xHotspot;
            public int yHotspot;
            public IntPtr hbmMask;
            public IntPtr hbmColor;
        }

        private void btnSave_Click(object sender, EventArgs e)
        {
            list.Save();
        }

     
    }
}
